|
ARD2
RC2
Airbag Reference Demonstrator using MPC5604P
|
00001 /***************************************************************************/ 00002 /* 00003 00004 FILE 00005 __ppc_eabi_init.c 00006 $Date: 2010/07/21 13:28:04 $ 00007 $Revision: 1.1 $ 00008 00009 DESCRIPTION 00010 00011 Use this file for C or C++. Contains calls to initialize memory pools 00012 for use with malloc/free, exceptions and static initializers. If your 00013 project does not use exceptions, then the initialization code for them 00014 is stripped out. If they are used, the linker will add them 00015 automatically. A C-only program will be a little smaller (160 bytes) 00016 with __ppc_eabi_init.c. 00017 00018 Interface for board-level initialization and user-level initialization. 00019 00020 If hardware initialization and pre-main user initialization are required, 00021 copy this file to your project directory and customize it (instead of 00022 customizing __start.c). 00023 00024 Note that __init_hardware should not write on the stack until the 00025 memory controller is properly configured. 00026 00027 00028 void __init_hardware(void) 00029 00030 Initialize the hardware, including the memory controller. 00031 00032 void __init_user(void) 00033 00034 Allow the user to perform initialization before calling main(). 00035 00036 void __init_cpp(void) 00037 00038 CodeWarrior C++ initialization before calling main(). Calls 00039 constructors of which the cpp exception handling initialization 00040 is the first constructor, if exceptions are used. 00041 00042 void __fini_cpp(void) 00043 00044 Calls destructors. 00045 00046 void _ExitProcess(void) 00047 00048 This function simply stalls the debugger. You may want to rewrite this 00049 function if you are using an OS. 00050 00051 abort and exit 00052 00053 In order to correctly implement the required startup/termination sequence for 00054 C and C++ programs, we need to have an exit() routine that can be called by 00055 the program startup code. The exit() routine is supposed to 00056 00057 (1) call any functions registered via atexit() 00058 (2) call destructors for any global objects 00059 (3) flush any unwritten buffers, close any open files, etc. 00060 (4) terminates the program 00061 00062 We don't, however, want to require the ANSI C library for every CodeWarrior 00063 program, since it drags in lots of code that may not be needed. 00064 00065 Instead we provide a dummy exit() function which simply calls the destructors 00066 and terminates the program. We assume that any program which uses atexit() 00067 or <stdio.h> and which requires those cleanup behaviors will have linked with 00068 the ANSI C library, whose definition of exit() will override the one here. 00069 00070 We similarly define a dummy abort() function (which is called by the default 00071 terminate() handler). 00072 00073 Programs which rely on the proper ANSI C/C++ behavior must use the ANSI C 00074 library, and order it in the CodeWarrior project or command-line so that 00075 its definitions supersede these definitions in the runtime support library. 00076 00077 COPYRIGHT 00078 (c) 2002-2006 Freescale Semiconductor, Inc. 00079 All rights reserved. 00080 00081 HISTORY 00082 97 APR 17 LLY Created. 00083 97 JUN 24 MEA Added support for C++ and malloc memory heaps. 00084 97 JUN 26 MEA Made C and C++ versions of this file. Added abort and exit. 00085 97 JUL 17 SCM Customized for MPC821 ADS board. 00086 97 JUL 20 MEA Changed __exit to _ExitProcess so as not to conflict with MSL. 00087 _ExitProcess added to this file; removed form __start.c. 00088 99 JAN 22 MEA Removed exception handing to __init_cpp_exceptions.c for use 00089 with 2.2.2 compiler (post Release 4). Put prototypes for 00090 exit and abort within extern "C" to avoid name-mangling. 00091 00092 */ 00093 /***************************************************************************/ 00094 00095 #pragma exceptions off 00096 #pragma ANSI_strict off 00097 #pragma only_std_keywords off 00098 00099 #define ALLOC_ADDITIONAL_HEAPS 0 00100 #include "MPC5604P.h" 00101 #define FLASH_REG CFLASH.PFCR0.R 00102 #define FLASH_DATA 0x108593FD 00103 /*$FlashRegister2$*/ 00104 /*$FlashRegisterValue2$*/ 00105 00106 00107 #include <__ppc_eabi_init.h> 00108 #include <__ppc_eabi_linker.h> /* linker-generated symbol declarations */ 00109 #if ALLOC_ADDITIONAL_HEAPS 00110 #include <pool_alloc.h> 00111 #endif 00112 00113 #ifdef __cplusplus 00114 extern "C" { 00115 #endif 00116 00117 static void __init_cpp(void); 00118 static void __fini_cpp(void); 00119 typedef void (*voidfunctionptr) (void); /* ptr to function returning void */ 00120 __declspec(section ".init") extern voidfunctionptr _ctors[]; 00121 __declspec(section ".init") extern voidfunctionptr _dtors[]; 00122 __declspec(weak) extern void abort(void); 00123 __declspec(weak) extern void exit(int status); 00124 extern void usr_init(); 00125 __declspec(section ".init") static int __get_runtime_linktime_delta(void); 00126 __declspec(section ".init") static int __get_linktime_address(void); 00127 __declspec(section ".init") static void __mwerks_fixup_relocations(void); 00128 00129 #ifdef __cplusplus 00130 } 00131 #endif 00132 00133 /***************************************************************************/ 00134 /* 00135 * __init_hardware 00136 * 00137 * Initialize the processor and board. 00138 * 00139 * Note: this function must not access memory until the memory controller 00140 * is initialized. Using "fralloc" (frame allocate) or writing this 00141 * function in C will cause this routine to break because writing into 00142 * stack memory is not valid until after usr_init returns. 00143 */ 00144 /***************************************************************************/ 00145 00146 asm void __init_hardware(void) 00147 { 00148 /* 00149 * Initialize board unless running with MWDebug. 00150 * Uncomment the initialization below if running standalone. 00151 * You may need to perform other initializations. 00152 */ 00153 nofralloc 00154 00155 /* 00156 * If we are using Hardware floating point we need to make sure 00157 * to enable the FP bit in the MSR 00158 */ 00159 00160 #if __option(floatingpoint)==1 && __option(sfp_emulation)==0 00161 mfmsr r3 00162 ori r3,r3,0x00002000 00163 mtmsr r3 00164 #endif 00165 00166 /* 00167 * If we have selected Altivec Programming Model we need to make sure 00168 * to enable the Altivec bit in the MSR 00169 */ 00170 00171 #if __VEC__ 00172 mfmsr r3 00173 oris r3,r3,0x0200 00174 mtmsr r3 00175 #endif 00176 00177 /* 00178 * Enable the MSR[SPE] bit for e500/Zen 00179 */ 00180 00181 #if defined(__PPCZen__) || defined(__PPCe500__) || defined(__PPCe500v2__) 00182 mfmsr r3 00183 oris r3,r3,0x0200 00184 mtmsr r3 00185 #endif 00186 00187 /* 00188 * When customizing, be aware that the memory controller may not be 00189 * configured. 00190 */ 00191 00192 #if defined(ROM_VERSION) || defined(CACHE_VERSION) || defined(CALL_USR_INIT) 00193 mflr r31 /* save off return address in NV reg */ 00194 bl usr_init /* init board hardware */ 00195 mtlr r31 /* get saved return address */ 00196 #endif 00197 00198 blr 00199 } 00200 00201 #if ALLOC_ADDITIONAL_HEAPS 00202 static void AllocMoreHeaps(void) 00203 { 00204 /* 00205 * By default, we MSL's allocation (malloc/free) even with C++. 00206 * If you have declared a heap size in the Project Pref panel, 00207 * a defaull heap will be created the first time you call 00208 * malloc. You can add more calls to init_alloc to create additional 00209 * heaps. 00210 */ 00211 init_alloc(some_address1, some_size1); 00212 init_alloc(some_address2, some_size2); 00213 } 00214 #endif 00215 void FlashConfig(void) 00216 { 00217 unsigned int mem_write_code [] = { 00218 00219 #if __option(vle) 00220 /*for processors which support VLE only or for 'VLE on' option*/ 00221 0xD0344400, /* stw r3,(0)r4 machine code: writes r3 contents to addr in r4 then se_nop*/ 00222 0x7C0006AC, /* mbar machine code: ensure prior store completed */ 00223 0x44000004 /* blr machine code: branches to return address in link register */ 00224 #else 00225 0x90640000, /* stw r3,(0)r4 machine code: writes r3 contents to addr in r4 */ 00226 0x7C0006AC, /* mbar machine code: ensure prior store completed */ 00227 0x4E800020 /* blr machine code: branches to return address in link register */ 00228 #endif // __option(vle) 00229 00230 }; 00231 00232 00233 typedef void (*mem_write_code_ptr_t)(unsigned int, unsigned int); 00234 00235 #if defined(FLASH_REG) 00236 (*((mem_write_code_ptr_t)mem_write_code)) /* cast mem_write_code as func ptr*/ 00237 /* * de-references func ptr, i.e. converts to func*/ 00238 (FLASH_DATA, /* which passes integer (in r3) */ 00239 (unsigned int)&FLASH_REG); 00240 #endif 00241 00242 #if defined(FLASH_REG2) 00243 (*((mem_write_code_ptr_t)mem_write_code)) /* cast mem_write_code as func ptr*/ 00244 /* * de-references func ptr, i.e. converts to func*/ 00245 (FLASH_DATA2, /* which passes integer (in r3) */ 00246 (unsigned int)&FLASH_REG2); 00247 #endif 00248 00249 } 00250 00251 asm void __init_user(void) 00252 { 00253 fralloc 00254 /* 00255 * Allocate additional heaps. 00256 */ 00257 #if ALLOC_ADDITIONAL_HEAPS 00258 bl AllocMoreHeaps 00259 #endif 00260 00261 /* 00262 * initialization of static initializers 00263 */ 00264 #if (defined(__cplusplus) || defined(__VEC__)) && !defined(DO_NOT_LOAD_CTORS_DTORS) 00265 bl __init_cpp 00266 #endif 00267 bl FlashConfig 00268 /* 00269 * Add your initializations here. 00270 */ 00271 frfree 00272 blr 00273 } 00274 00275 #if defined(__cplusplus) || defined(__VEC__) 00276 static void __init_cpp(void) 00277 { 00278 voidfunctionptr *constructor; 00279 00280 /* 00281 * call static initializers 00282 */ 00283 for (constructor = _ctors; *constructor; constructor++) { 00284 (*constructor)(); 00285 } 00286 } 00287 00288 static void __fini_cpp(void) 00289 { 00290 voidfunctionptr *destructor; 00291 00292 /* 00293 * call destructors 00294 */ 00295 for (destructor = _dtors; *destructor; destructor++) { 00296 (*destructor)(); 00297 } 00298 } 00299 #endif 00300 00301 extern void abort(void) 00302 { 00303 _ExitProcess(); 00304 } 00305 00306 extern void exit(int status) 00307 { 00308 #pragma unused(status) 00309 00310 #if (defined(__cplusplus) || defined(__VEC__)) && !defined(DO_NOT_LOAD_CTORS_DTORS) 00311 __fini_cpp(); 00312 #endif 00313 _ExitProcess(); 00314 } 00315 00316 00317 /* 00318 * _ExitProcess 00319 * 00320 * PowerPC EABI Runtime termination 00321 */ 00322 asm void _ExitProcess(void) 00323 { 00324 nofralloc 00325 00326 #if VLE_ON 00327 /* the inline assembler can not translate this instruction */ 00328 se_illegal /* arbitrary break trap for halt */ 00329 #else 00330 opword 0x00454E44 /* arbitrary break trap for halt */ 00331 #endif 00332 } 00333 00334 /****************************************************************************/ 00335 /* 00336 * __flush_cache 00337 * 00338 * For the given memory range, forces all modified data cache contents to be 00339 * written to memory and invalidates the associated instruction cache 00340 * entries. 00341 * 00342 */ 00343 /****************************************************************************/ 00344 asm void __flush_cache(register void *address, register unsigned int size) 00345 { 00346 #pragma unused (address, size) 00347 /* r3 is address, r4 is size */ 00348 nofralloc 00349 00350 #if !defined( __PPC555__ ) && !defined( __PPC56X__ ) 00351 #if VLE_ON 00352 /* the inline assembler can not translate 2 instructions into 1 */ 00353 e_li r5,0xFFFFFFF1 00354 #else 00355 lis r5, 0xffff 00356 ori r5, r5, 0xfff1 00357 #endif 00358 and r5, r5, r3 /* make address 8-byte aligned */ 00359 subf r3, r5, r3 /* get unaligned-aligned difference */ 00360 add r4, r4, r3 /* increase size accordingly */ 00361 00362 rept: 00363 /* 00364 ** Note: If no data cache, then just invalidate the instruction 00365 ** cache entry. 00366 ** 00367 ** The MPC 5xx processors do not have data cache. 00368 */ 00369 #if !defined( __PPC505__ ) && !defined( __PPC509__ ) 00370 00371 #if !defined(__PPCGENERIC__) 00372 dcbst 0,r5 00373 #endif 00374 00375 #endif 00376 00377 #if defined(__PPCZen__) || defined(__PPCe500__) || defined(__PPCe500v2__) 00378 #if VLE_ON 00379 se_isync 00380 #else 00381 msync 00382 #endif 00383 #else 00384 sync 00385 #endif 00386 00387 00388 #if !defined(__PPCGENERIC__) 00389 icbi 0,r5 00390 #endif 00391 00392 addic r5,r5,0x8 00393 subic. r4,r4,0x8 00394 bge rept 00395 isync 00396 #endif 00397 blr 00398 } 00399 00400 #if __option(sda_pic_pid) 00401 /* The following functions are used with SDA PIC/PID support. */ 00402 /* __init_registers and __init_data will overload weak versions found in __start.c */ 00403 00404 /*************************************************************************** 00405 *** Requirements for SDA PIC/PID *** 00406 00407 The basic requirement for SDA PIC/PID is that the startup code (.init) and 00408 the segments .sdata and .sdata2 all maintain their link time address 00409 relationship at runtime. In other words if the link time addresses are: 00410 .init = 0x00002000 00411 .sdata2 = 0x00003000 00412 .sdata = 0x00004000 00413 but that .init somehow is executed at 0x00002500, then those link time 00414 addresses must all increment by 0x00000500 for their runtime addresses. 00415 Any segment that does not maintain the address relationship at runtime is 00416 considered external and must be addressed with absolute addresses. 00417 Segments that do maintain their link time address relationship at runtime 00418 are considered internal and must be addressed with pc and sda relative 00419 addressing. More on external and internal segments, below. 00420 00421 Having .init, .sdata2 and .sdata, as well as other internal segments, end 00422 up at runtime without the link time relationship is not detected in this 00423 runtime but it is at least technically possible for someone to modify the 00424 runtime to support this, at least for a specific application. 00425 00426 *** Internal and External segments and references *** 00427 00428 At link time, the linker determines whether code and data segments are 00429 external or internal. Internal segments reference their data as far or 00430 near offsets of the small data registers r2 and r13. Their code 00431 references are normally pc relative, but if far code references are 00432 required, they also use offsets of the small data registers. Internal 00433 segments can also reference code and data in other internal segments 00434 with the same addressing that they would use for their own code ad data. 00435 By default, all segments in your application are considered internal with 00436 one exception listed below. 00437 00438 External segments are segments that are at absolute addresses. 00439 Segments with a name like .abs.xxxxxxxx, where xxxxxxxx is a hex address 00440 are considered external. External segments reference their data with 00441 absolute addressing and code references within the segment can be pc 00442 relative or absolute. Any other segment must use absolute references 00443 to reference code or data in external segments. External segments must 00444 reference an internal segment with small data registers for code and data. 00445 00446 Akin to external segments are external symbol references. These are 00447 symbols, usually linker generated symbols, that are determined to be not 00448 within any segment in your application. They will be referenced with 00449 absolute addressing. All symbols in an external segment are considered 00450 to be external symbol references. 00451 00452 The ldf has 2 mechanisms for you to override the linker's defaults: 00453 1. The MEMORY directive now supports 00454 addr_mode = external | internal // default is internal 00455 addr_mode is ignored unless you have chosen the SDA PIC/PID ABI in the EPPC 00456 Target Pref panel. 00457 00458 2. New directives INTERNAL_SYMBOL and EXTERNAL_SYMBOL can be used to force 00459 the addressing of global symbols. These directives are of the 00460 form XXXL_SYMBOL { sym1, sym2, symN } where the symbols are the link time 00461 symbol names (mangled for c++). 00462 00463 The auto-generated linker defined start and end symbols for loadable 00464 segments are internal if they are addresses into internal segments and 00465 external if they are for external segments. All other linker defined 00466 symbols you create in a lcf are considered external unless you redefine 00467 them with INTERNAL_SYMBOL. The linker also defines some linker defined 00468 symbols for its own use and they have the following default settings: 00469 00470 _stack_addr [top of the stack - comes from pref panel settings] external 00471 _stack_end [bottom of the stack - comes from pref panel settings] external 00472 _heap_addr [bottom of the heap - comes from pref panel settings] external 00473 _heap_end [top of the heap - comes from pref panel settings] external 00474 // the next two need to be treated as internal to be EABI compliant so 00475 // you may not redefine them. 00476 _SDA_BASE_ [.sdata + 0x00008000] internal 00477 _SDA2_BASE_ [.sdata2 + 0x00008000] internal 00478 // The previous small data pointers rely on the small data registers being 00479 // properly initialized before being accessible. However, it is hard to 00480 // initialize those pointers without accessing them as absolutes. 00481 // The following two symbols are external versions of _SDA_BASE_ and 00482 // _SDA2_BASE_ which can be used as absolutes. You may not redefine them. 00483 _ABS_SDA_BASE_ [.sdata + 0x00008000] external 00484 _ABS_SDA2_BASE_ [.sdata2 + 0x00008000] external 00485 // the following are numbers, not addresses and they must be treated 00486 // as external. You may not redefine them. 00487 _nbfunctions [number of functions in program - deprecated] external 00488 SIZEOF_HEADERS [size of the segment headers in a linux app] external 00489 00490 Especially note that the stack and heap linker generated symbols are 00491 external. It may be more practical in a SDA PIC/PID application to 00492 make the heap and stack be contiguous with an internal segment and 00493 define them as internal. 00494 00495 *** Uses for SDA PIC/PID *** 00496 00497 The runtime was developed for 3 different situations: 00498 00499 1. All code and data segments are internal. The simplest case would be 00500 for all segments to use the same MEMORY directive and to have all of the 00501 bss type segments at the end. In such a simple case, the application could 00502 be converted to a binary file and linked into another application which 00503 could copy it to ram and jump to its entry point. 00504 00505 2. All of the essential segments are internal and therefore moveable but 00506 there may be some external segments which are absolute. This situation is 00507 probably difficult to test but you can download the entire application 00508 to the chip and at least debug it at its link time addresses. 00509 00510 3. Like 2, there are internal and external segments but the application is 00511 linked as a ROM image - the application does not need to be flashed to 00512 ROM, however. It is possible to change the ROM Image Address to be an 00513 address into RAM and have the debugger download the image to the RAM 00514 address. Alternatively, you could have the ROM image converted to a bin 00515 file and link it into another application as in 1, above. The structures 00516 used in __init_data(), _rom_copy_info and __bss_init_info, have been 00517 modified for SDA PIC/PID to have an extra field which tells the runtime 00518 where the segment is internal or external so that the internal segments 00519 will be copied to position relative addresses and the external segments 00520 will be copied to absolute addresses. 00521 00522 *** Compiler/Linker support for SDA Addressing *** 00523 You build a SDA PIC/PID application by selecting SDA PIC/PID in the ABI 00524 popup in the EPPC Target Preference panel. When you chose that, the 00525 compiler will define a simple that you can use to guard PIC/PID source. 00526 00527 #if __option(sda_pic_pid) // is true if you have chosen SDA PIC/PID ABI 00528 00529 If you then link, the linker will generate a table for the runtime files 00530 __ppc_eabi_init.cpp/__ppc_eabi_init.c to use. If your application has 00531 absolute addressing relocations (which it would by default) you will 00532 probably get linker warnings telling you that those relocations may 00533 cause a problem. If that happens, you have two choices. You can change 00534 the Code Model popup in the EPPC Target Preference panel to be 00535 SDA Based PIC/PID Addressing for all of your sources and libraries, and/or 00536 check the Tune Relocations checkbox in the EPPC Target Preference panel. 00537 This new option is only available for the EABI and SDA PIC/PID ABIs. For 00538 EABI it changes 14 bit branch relocations to 24 bit branch relocations 00539 only if they can not reach the calling site from the original relocation. 00540 For SDA PIC/PID, it changes absolute addressed references of data from 00541 code to use a small data register instead of r0 and changes absolute 00542 code to code refernces to use the pc relative relocations. In general, 00543 this will work well for normnal compiled code. It is always possible 00544 to link in an assembly file that does not behave in a standard way. 00545 00546 Whether you use the Code Model SDA Based PIC/PID Addressing or not, 00547 #pragma section has been modified to accept far_sda_rel for the data_mode 00548 and code_mode options. If you leave those options out, the compiler 00549 will you the Code Model to determine the appropriate modes. 00550 00551 Absolute Addressing defaults to data_mode = far_abs and code_mode = pc_rel. 00552 SDA Based PIC/PID Addressing defaults to data_mode = far_sda_rel and 00553 code_mode = pc_rel. 00554 00555 ***************************************************************************/ 00556 00557 /***************************************************************************/ 00558 /* 00559 * __get_runtime_linktime_delta 00560 * 00561 * Assumes that r13 and r2 are initialized correctly and that they always 00562 * stay in the same relationship to each other. 00563 * 00564 * Utility function to get difference between runtime and linktime addresses. 00565 * 00566 */ 00567 /***************************************************************************/ 00568 static asm int __get_runtime_linktime_delta(void) 00569 { 00570 nofralloc 00571 /* _ABS_SDA_BASE_, generated by the linker, is the same value as */ 00572 /* _SDA_BASE_ but forces the linker to treat it as absolutetly addressed */ 00573 /* and not to substitute r13 for r0. We therefore end up with r3 exactly */ 00574 /* as calculated at linktime. */ 00575 addis r3, r0, _ABS_SDA_BASE_@ha 00576 addi r3, r3, _ABS_SDA_BASE_@l 00577 /* Subtract the runtime from the linktime address. */ 00578 sub r3,r13,r3 00579 blr 00580 } 00581 00582 /***************************************************************************/ 00583 /* 00584 * __mwerks_fixup_relocations 00585 * 00586 * Modify initialized pointers in the data sections to reflect correct 00587 * runtime addresses. The linker created a table, _f_mwerks_fixup, of 00588 * offsets into the data sections that need modification. This function 00589 * loads the pointer at that offset and applies the runtime/linktime 00590 * delta. We wait to call this function until after __init_data. 00591 * 00592 */ 00593 /***************************************************************************/ 00594 static asm void __mwerks_fixup_relocations(void) 00595 { 00596 nofralloc 00597 00598 /* r13, r2, and r1 have their correct runtime values. */ 00599 00600 mflr r0 00601 00602 /* If runtime and linktime addresses are the same, no fixup is necessary. */ 00603 bl __get_runtime_linktime_delta 00604 cmpli cr0,r3,0 00605 beq no_fixup 00606 00607 /* Initialize runtime addresses of the fixup table. _f_mwerks_fixup is the */ 00608 /* beginning of the table and _e_mwerks_fixup is the end. Note that r0 */ 00609 /* will get converted to r13 or r2 by the linker. */ 00610 addis r5,r0,_f_mwerks_fixup@ha 00611 addis r4,r0,_e_mwerks_fixup@ha 00612 addi r5,r5,_f_mwerks_fixup@l 00613 addi r4,r4,_e_mwerks_fixup@l 00614 00615 /* Compute number of entries ((_e_mwerks_fixup - _f_mwerks_fixup) / 4). */ 00616 subf r6,r5,r4 00617 /* If there are no entries, bail. */ 00618 cmpli cr0,r6,0 00619 beq no_fixup 00620 srwi r6,r6,2 00621 mtctr r6 00622 /* We use pre-increment, so move to first real entry - 4. */ 00623 subi r5,r5,4 00624 fixup_loop: 00625 /* Load address of relocation. */ 00626 lwzu r6,4(r5) 00627 /* Update address using SDA delta. */ 00628 add r6,r6,r3 00629 /* Load value at relocation. */ 00630 lwz r7,0(r6) 00631 /* Update value using SDA delta. */ 00632 add r7,r7,r3 00633 /* Store updated value. */ 00634 stw r7,0(r6) 00635 bdnz fixup_loop 00636 no_fixup: 00637 mtlr r0 00638 blr 00639 } 00640 00641 /***************************************************************************/ 00642 /* 00643 * __init_registers 00644 * 00645 * Initialize PowerPC EABI Registers 00646 * 00647 * Note: this function is guaranteed to not reference any memory; the memory 00648 * controller may not be initialized. 00649 * 00650 * we now overload the function in the event that the user wants pic pid 00651 * 00652 */ 00653 /***************************************************************************/ 00654 asm extern void __init_registers(void) 00655 { 00656 nofralloc /* see above on usage of nofralloc */ 00657 00658 mflr r0 00659 00660 /* _ABS_SDA_BASE_, generated by the linker, is the same value as */ 00661 /* _SDA_BASE_ but forces the linker to treat it as absolutetly addressed */ 00662 /* and not to substitute r13 for r0. We therefore end up with r13 exactly */ 00663 /* as calculated at linktime. */ 00664 addis r13, r0, _ABS_SDA_BASE_@ha 00665 addi r13, r13, _ABS_SDA_BASE_@l 00666 00667 /* _ABS_SDA2_BASE_, generated by the linker, is the same value as */ 00668 /* _SDA2_BASE_ but forces the linker to treat it as absolutetly addressed */ 00669 /* and not to substitute r2 for r0. We therefore end up with r2 exactly */ 00670 /* as calculated at linktime. */ 00671 addis r2, r0, _ABS_SDA2_BASE_@ha 00672 addi r2, r2, _ABS_SDA2_BASE_@l 00673 00674 /* Grab the runtime address of __get_linktime_address. The bcl will put */ 00675 /* __get_linktime_address into LR. */ 00676 bcl 20,31,__get_linktime_address 00677 entry __get_linktime_address 00678 /* Move runtime address of __get_linktime_address from LR to r4. */ 00679 mflr r4 00680 00681 /* Grab the linktime address of __get_linktime_address. Note that r0 will */ 00682 /* get converted to r13 or r2 by the linker but because r13 and r2 may not */ 00683 /* reflect the their runtime values yet, r3 might not equal r4. */ 00684 addis r3,r0,__get_linktime_address@ha 00685 addi r3,r3,__get_linktime_address@l 00686 00687 /* Subtract the runtime from the linktime address. */ 00688 sub r3,r4,r3 00689 /* If runtime and linktime addresses are the same, no fixup is necessary. */ 00690 cmpli cr0,r3,0 00691 beq no_fixup 00692 00693 /* Add the delta into small data pointers so they will reflect the current */ 00694 /* position of code and data. */ 00695 add r13,r13,r3 00696 add r2,r2,r3 00697 no_fixup: 00698 00699 /* Initialize runtime address of _stack_addr. Note that r0 will */ 00700 /* get converted to r13 or r2 by the linker if _stack_addr is */ 00701 /* treated as an internal symbol (default is external). */ 00702 addis r1, r0, _stack_addr@ha 00703 addi r1, r1, _stack_addr@l 00704 mtlr r0 00705 00706 blr 00707 } 00708 00709 /***************************************************************************/ 00710 /* 00711 * __init_data 00712 * 00713 * Initialize all (RAM) data sections, copying ROM sections as necessary. 00714 * 00715 * dst destination RAM address 00716 * size number of bytes to zero 00717 * 00718 * we now overload the function in the event that the user wants pic pid 00719 * 00720 */ 00721 /***************************************************************************/ 00722 extern void __init_data(void) 00723 { 00724 __pic_rom_copy_info *dci; 00725 __pic_bss_init_info *bii; 00726 int delta = __get_runtime_linktime_delta(); 00727 unsigned int size; 00728 unsigned char *ram_addr; /* address in ram (executing address) */ 00729 unsigned char *ram_end; /* end address in ram (executing address) */ 00730 unsigned char *rom_addr; /* address in rom */ 00731 unsigned char *rom_end; /* end address in rom */ 00732 int internal; 00733 00734 /* for sda pic pid, if ram_end and ram_addr are swapped so that ram_end < ram_addr, */ 00735 /* then segment is internal, otherwise it is external. for eabi, addresses are external */ 00736 00737 dci = _pic_rom_copy_info; 00738 while (1) { 00739 if (dci->rom_addr == 0 && dci->ram_addr == 0 && dci->ram_end == 0) break; 00740 internal = (dci->rom_end < dci->rom_addr); 00741 if (internal) { 00742 rom_addr = dci->rom_end + delta; 00743 rom_end = dci->rom_addr + delta; 00744 } else { 00745 rom_addr = dci->rom_addr; 00746 rom_end = dci->rom_end; 00747 } 00748 internal = (dci->ram_end < dci->ram_addr); 00749 if (internal) { 00750 ram_addr = dci->ram_end + delta; 00751 ram_end = dci->ram_addr + delta; 00752 } else { 00753 ram_addr = dci->ram_addr; 00754 ram_end = dci->ram_end; 00755 } 00756 size = (unsigned int) (ram_end - ram_addr); 00757 __copy_rom_section(ram_addr, rom_addr, size); 00758 dci++; 00759 } 00760 00761 /* Initialize with zeros: */ 00762 00763 bii = _pic_bss_init_info; 00764 while (1) { 00765 if (bii->ram_addr == 0 && bii->ram_end == 0) break; 00766 internal = (bii->ram_end < bii->ram_addr); 00767 if (internal) { 00768 ram_addr = bii->ram_end + delta; 00769 ram_end = bii->ram_addr + delta; 00770 } else { 00771 ram_addr = bii->ram_addr; 00772 ram_end = bii->ram_end; 00773 } 00774 size = (unsigned int) (ram_end - ram_addr); 00775 __init_bss_section(ram_addr, size); 00776 bii++; 00777 } 00778 00779 /* now that data is copied to ram, we can fix up initialized pointers */ 00780 __mwerks_fixup_relocations(); 00781 } 00782 00783 /***************************************************************************/ 00784 /* 00785 * __exception_info_constants 00786 * 00787 * Called from __init_cpp_exceptions.cpp 00788 * 00789 * info address of linker generated exception table info 00790 * R2 address of variable to hold the value in r2 00791 * 00792 * we now overload the function in the event that the user wants pic pid 00793 * 00794 */ 00795 /***************************************************************************/ 00796 extern void __exception_info_constants(void **info, char **R2) 00797 { 00798 register char *temp; /* r2 register contents */ 00799 00800 asm { 00801 mr temp,r2 00802 } 00803 *R2 = temp; 00804 00805 *info = _pic_eti_init_info; 00806 } 00807 00808 /***************************************************************************/ 00809 /* 00810 * __find_exception_addresses 00811 * 00812 * Called from ExceptionPPC.cp 00813 * 00814 * info address of linker generated exception table info 00815 * returnaddr address within a code segment 00816 * returnaddr address within a code segment 00817 * ex_start address of variable to hold address of exception table info 00818 * ex_end address of variable to hold end address of exception table info 00819 * 00820 * we now overload the function in the event that the user wants pic pid 00821 * 00822 */ 00823 /***************************************************************************/ 00824 extern int __find_exception_addresses(void *info, char *returnaddr, void **ex_start, void **ex_end) 00825 { 00826 __pic_eti_init_info *eti_info = (__pic_eti_init_info*)info; 00827 unsigned char *start; /* address */ 00828 unsigned char *end; /* end address */ 00829 int internal; 00830 int delta = __get_runtime_linktime_delta(); 00831 00832 while (1) { 00833 if (eti_info->code_end - eti_info->code_start == 0) break; 00834 internal = (eti_info->code_end < eti_info->code_start); 00835 if (internal) { 00836 start = eti_info->code_end + delta; 00837 end = eti_info->code_start + delta; 00838 } else { 00839 start = eti_info->code_start; 00840 end = eti_info->code_end; 00841 } 00842 if((unsigned char*)returnaddr>=start && (unsigned char*)returnaddr<end) { 00843 internal = (eti_info->eti_end < eti_info->eti_start); 00844 if (internal) { 00845 start = eti_info->eti_end + delta; 00846 end = eti_info->eti_start + delta; 00847 } else { 00848 start = eti_info->eti_start; 00849 end = eti_info->eti_end; 00850 } 00851 *ex_start = start; 00852 *ex_end = end; 00853 return(1); 00854 } 00855 eti_info++; 00856 } 00857 00858 return(0); 00859 } 00860 00861 00862 #endif